import WebSocket from 'ws';
import * as CryptoJS from 'crypto-js';

// 配置参数（实际使用时应替换为您的真实值）
const CONFIG = {
  WS_URL: "wss://ws.okx.com:8443/ws/v5/private",  // WebSocket服务器地址
  API_KEY: "a1142c12-c3a5-44d6-a3a9-782f9077c682",
  SECRET_KEY: "562D22EFC390005CD01DCFECD376CD6E",
  PASSPHRASE: "!Zjj135886531"
};

// 类型定义
interface LoginRequest {
  op: string;
  args: Array<{
    apiKey: string;
    passphrase: string;
    timestamp: string;
    sign: string;
  }>;
}

interface LoginSuccessResponse {
  event: 'login';
  code: string;
  msg: string;
  connId: string;
}

interface ErrorResponse {
  event: 'error';
  code: string;
  msg: string;
  connId: string;
}

type WsResponse = LoginSuccessResponse | ErrorResponse;

class OKXWebSocketClient {
  private ws: WebSocket;
  private connId: string | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;

  constructor() {
    this.ws = new WebSocket(CONFIG.WS_URL);
    this.setupEventListeners();
  }

  private setupEventListeners(): void {
    this.ws.on('open', () => {
      console.log('✅ WebSocket connected');
      this.reconnectAttempts = 0; // 重置重连计数器
      this.login();
    });

    this.ws.on('message', (data: WebSocket.Data) => {
      try {
        const response = JSON.parse(data.toString()) as WsResponse;
        this.handleResponse(response);
      } catch (err) {
        console.error('❌ Message parsing error:', err);
      }
    });

    this.ws.on('error', (err) => {
      console.error('❌ WebSocket error:', err);
    });

    this.ws.on('close', () => {
      console.log('⚠️ WebSocket disconnected');
      this.handleReconnect();
    });
  }

  private generateSign(timestamp: string): string {
    const method = 'GET';
    const requestPath = '/users/self/verify';
    const message = `${timestamp}${method}${requestPath}`;
    const hmac = CryptoJS.HmacSHA256(message, CONFIG.SECRET_KEY);
    return CryptoJS.enc.Base64.stringify(hmac);
  }

  private getTimestamp(): string {
    return Math.floor(Date.now() / 1000).toString();
  }

  private login(): void {
    const timestamp = this.getTimestamp();
    const sign = this.generateSign(timestamp);

    const loginRequest: LoginRequest = {
      op: 'login',
      args: [{
        apiKey: CONFIG.API_KEY,
        passphrase: CONFIG.PASSPHRASE,
        timestamp,
        sign
      }]
    };

    console.log('🔑 Sending login request...');
    this.ws.send(JSON.stringify(loginRequest));
  }

  private handleResponse(response: WsResponse): void {
    if (response.event === 'login' && response.code === '0') {
      this.connId = response.connId;
      console.log(`🎉 Login success! Connection ID: ${this.connId}`);
      this.startHeartbeat();
    } else if (response.event === 'error') {
      console.error(`❌ Login failed (Code ${response.code}): ${response.msg}`);
    }
  }

  private startHeartbeat(): void {
    setInterval(() => {
      if (this.ws.readyState === WebSocket.OPEN) {
        this.ws.ping();
      }
    }, 30000); // 每30秒发送一次心跳
  }

  private handleReconnect(): void {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
      
      console.log(`♻️ Attempting reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts}) in ${delay}ms...`);
      
      setTimeout(() => {
        this.ws = new WebSocket(CONFIG.WS_URL);
        this.setupEventListeners();
      }, delay);
    } else {
      console.error('⛔ Maximum reconnect attempts reached');
    }
  }
}

// 启动客户端
new OKXWebSocketClient();

console.log('🚀 WebSocket client initialized');